use crate::{Code, Key, Location, Metas};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum State {
	Down,
	Up,
}
#[derive(Debug, Clone)]
pub struct Keyboard {
	pub key: Key,
	pub code: Code,
	pub state: State,
	pub location: Location,
	pub metas: Metas,
	pub repeat: bool,
	pub composing: bool,
}
impl Keyboard {
	pub fn new(key: Key, code: Code, state: State, location: Location, metas: Metas, repeat: bool, composing: bool) -> Self {
		Self {
			key,
			code,
			state,
			location,
			metas,
			repeat,
			composing,
		}
	}
}
impl From<Code> for Location {
	fn from(code: Code) -> Self {
		use Code as KeyCode;
		use Location as KeyLocation;
		match code {
			KeyCode::MetaRight => KeyLocation::Right,
			KeyCode::MetaLeft => KeyLocation::Left,
			KeyCode::ShiftLeft => KeyLocation::Left,
			KeyCode::AltLeft => KeyLocation::Left,
			KeyCode::ControlLeft => KeyLocation::Left,
			KeyCode::ShiftRight => KeyLocation::Right,
			KeyCode::AltRight => KeyLocation::Right,
			KeyCode::ControlRight => KeyLocation::Right,

			KeyCode::NumLock => KeyLocation::Numpad,
			KeyCode::NumpadDecimal => KeyLocation::Numpad,
			KeyCode::NumpadMultiply => KeyLocation::Numpad,
			KeyCode::NumpadAdd => KeyLocation::Numpad,
			KeyCode::NumpadDivide => KeyLocation::Numpad,
			KeyCode::NumpadEnter => KeyLocation::Numpad,
			KeyCode::NumpadSubtract => KeyLocation::Numpad,
			KeyCode::NumpadEqual => KeyLocation::Numpad,
			KeyCode::Numpad0 => KeyLocation::Numpad,
			KeyCode::Numpad1 => KeyLocation::Numpad,
			KeyCode::Numpad2 => KeyLocation::Numpad,
			KeyCode::Numpad3 => KeyLocation::Numpad,
			KeyCode::Numpad4 => KeyLocation::Numpad,
			KeyCode::Numpad5 => KeyLocation::Numpad,
			KeyCode::Numpad6 => KeyLocation::Numpad,
			KeyCode::Numpad7 => KeyLocation::Numpad,
			KeyCode::Numpad8 => KeyLocation::Numpad,
			KeyCode::Numpad9 => KeyLocation::Numpad,

			_ => KeyLocation::Standard,
		}
	}
}
impl From<Code> for Key {
	fn from(code: Code) -> Self {
		type KeyCode = Code;
		type NamedKey = Key;
		match code {
			KeyCode::Enter => NamedKey::Enter,
			KeyCode::Tab => NamedKey::Tab,
			KeyCode::Space => NamedKey::Character(" ".into()),
			KeyCode::Backspace => NamedKey::Backspace,
			KeyCode::Escape => NamedKey::Escape,
			KeyCode::MetaRight => NamedKey::Super,
			KeyCode::MetaLeft => NamedKey::Super,
			KeyCode::ShiftLeft => NamedKey::Shift,
			KeyCode::AltLeft => NamedKey::Alt,
			KeyCode::ControlLeft => NamedKey::Control,
			KeyCode::ShiftRight => NamedKey::Shift,
			KeyCode::AltRight => NamedKey::Alt,
			KeyCode::ControlRight => NamedKey::Control,

			KeyCode::NumLock => NamedKey::NumLock,
			KeyCode::AudioVolumeUp => NamedKey::AudioVolumeUp,
			KeyCode::AudioVolumeDown => NamedKey::AudioVolumeDown,

			KeyCode::NumpadEnter => NamedKey::Enter,

			KeyCode::F1 => NamedKey::F1,
			KeyCode::F2 => NamedKey::F2,
			KeyCode::F3 => NamedKey::F3,
			KeyCode::F4 => NamedKey::F4,
			KeyCode::F5 => NamedKey::F5,
			KeyCode::F6 => NamedKey::F6,
			KeyCode::F7 => NamedKey::F7,
			KeyCode::F8 => NamedKey::F8,
			KeyCode::F9 => NamedKey::F9,
			KeyCode::F10 => NamedKey::F10,
			KeyCode::F11 => NamedKey::F11,
			KeyCode::F12 => NamedKey::F12,
			KeyCode::F13 => NamedKey::F13,
			KeyCode::F14 => NamedKey::F14,
			KeyCode::F15 => NamedKey::F15,
			KeyCode::F16 => NamedKey::F16,
			KeyCode::F17 => NamedKey::F17,
			KeyCode::F18 => NamedKey::F18,
			KeyCode::F19 => NamedKey::F19,
			KeyCode::F20 => NamedKey::F20,

			KeyCode::Insert => NamedKey::Insert,
			KeyCode::Home => NamedKey::Home,
			KeyCode::PageUp => NamedKey::PageUp,
			KeyCode::Delete => NamedKey::Delete,
			KeyCode::End => NamedKey::End,
			KeyCode::PageDown => NamedKey::PageDown,
			KeyCode::ArrowLeft => NamedKey::ArrowLeft,
			KeyCode::ArrowRight => NamedKey::ArrowRight,
			KeyCode::ArrowDown => NamedKey::ArrowDown,
			KeyCode::ArrowUp => NamedKey::ArrowUp,
			_ => NamedKey::Unidentified(0),
		}
	}
}
